﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;

namespace com.uplus.common.Tools
{
    public class ZipHelper
    {
        #region 解压zip格式的文件
        /// <summary>
        /// 功能：解压zip格式的文件
        /// </summary>
        /// <param name="zipFilePath">压缩文件路径</param>
        /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下，跟压缩文件同名的文件夹</param>
        public static void UnZip(string zipFilePath, string unZipDir)
        {
            if (zipFilePath == string.Empty)
            {
                throw new Exception("压缩文件路径不能为空！");
            }
            if (!File.Exists(zipFilePath))
            {
                throw new FileNotFoundException("压缩文件不存在！");
            }

            //解压文件夹为空时默认与压缩文件同一级目录下，跟压缩文件同名的文件夹  
            if (unZipDir == string.Empty)
                unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));

            if (!unZipDir.EndsWith("/"))
                unZipDir += "/";

            if (!Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);

            try
            {
                //byte[] fileBuffer1 = Convert.FromBase64String(zipFilePath);
                //FileSystem.Bytes2File(fileBuffer1, unZipDir);
                ////添加文件到指定压缩文件中
                //ZipFile.CreateFromDirectory(zipFilePath, unZipDir);
                ////删除文件夹下的所有文件
                //FileSystem.DeleteDirAllFile(unZipDir); //Directory.GetCurrentDirectory() + "/wwwroot/file/"
                ////文件转成byte二进制数组
                //byte[] fileBuffer = FileSystem.File2Bytes(zipFilePath);

                //将指定 zip 存档中的所有文件都解压缩到文件系统的一个目录下
                ZipFile.ExtractToDirectory(zipFilePath, unZipDir, Encoding.UTF8); //webRootPath + "/file" //Directory.GetCurrentDirectory() + "/wwwroot/file"
            }
            catch (Exception ex)
            {

                throw;
            }

        }
        #endregion


        #region 压缩单个文件
        public void ZipOneFile(string filePath, string zipedFileName, int compressionLevel = 9)
        {
            // 如果文件没有找到，则报错 
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("文件：" + filePath + "没有找到！");
            }
            // 如果压缩后名字为空就默认使用源文件名称作为压缩文件名称
            if (string.IsNullOrEmpty(zipedFileName))
            {
                string oldValue = Path.GetFileName(filePath);
                if (oldValue != null)
                {
                    zipedFileName = filePath.Replace(oldValue, "") + Path.GetFileNameWithoutExtension(filePath) + ".zip";
                }
            }
            // 如果压缩后的文件名称后缀名不是zip，就是加上zip，防止是一个乱码文件
            if (Path.GetExtension(zipedFileName) != ".zip")
            {
                zipedFileName = zipedFileName + ".zip";
            }
            // 如果指定位置目录不存在，创建该目录  C:\Users\yhl\Desktop\XXX
            string zipedDir = zipedFileName.Substring(0, zipedFileName.LastIndexOf("\\", StringComparison.Ordinal));
            if (!Directory.Exists(zipedDir))
            {
                Directory.CreateDirectory(zipedDir);
            }
            // 被压缩文件名称
            string filename = filePath.Substring(filePath.LastIndexOf("\\", StringComparison.Ordinal) + 1);
            var streamToZip = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            var zipFile = File.Create(zipedFileName);
            //var zipStream = new ZipOutputStream(zipFile);

        }
        public void ZipOneFile(string fileToZip, string zipedFile)
        {

        }
        #endregion

        #region 压缩文件夹
        /// <summary>
        /// 压缩文件夹
        /// </summary>
        /// <param name="dirToZip"></param>
        /// <param name="zipedFileName"></param>
        /// <param name="compressionLevel">压缩率0（无压缩）9（压缩率最高）</param>
        public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)
        {

        }
        #endregion

        #region 压缩多个目录或文件
        public void ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
        {

        }
        #endregion

        #region 获取所有文件
        public Hashtable GetAllFies(string dir)
        {
            Hashtable filesList = new Hashtable();
            DirectoryInfo fileDir = new DirectoryInfo(dir);
            if (!fileDir.Exists)
            {
                throw new FileNotFoundException("目录:" + fileDir.FullName + "没有找到!");
            }
            GetAllDirFiles(fileDir, filesList);
            GetAllDirsFiles(fileDir.GetDirectories(), filesList);
            return filesList;
        }
        //获取一个文件夹下的所有文件夹里的文件  
        public void GetAllDirsFiles(IEnumerable<DirectoryInfo> dirs, Hashtable filesList)
        {
            foreach (DirectoryInfo dir in dirs)
            {
                foreach (FileInfo file in dir.GetFiles("*.*"))
                {
                    filesList.Add(file.FullName, file.LastWriteTime);
                }
                GetAllDirsFiles(dir.GetDirectories(), filesList);
            }
        }
        //获取一个文件夹下的文件  
        public static void GetAllDirFiles(DirectoryInfo dir, Hashtable filesList)
        {
            foreach (FileInfo file in dir.GetFiles("*.*"))
            {
                filesList.Add(file.FullName, file.LastWriteTime);
            }
        }
        #endregion
    }

    public class FileSystem
    {
        /// <summary>
        /// 将byte数组转换为文件并保存到指定地址
        /// </summary>
        /// <param name="buff">byte数组</param>
        /// <param name="savepath">保存地址</param>
        public static void Bytes2File(byte[] buff, string savepath)
        {
            if (File.Exists(savepath))
            {
                File.Delete(savepath);
            }

            FileStream fs = new FileStream(savepath, FileMode.CreateNew);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(buff, 0, buff.Length);
            bw.Close();
            fs.Close();
        }

        /// <summary>
        /// 将文件转换为byte数组
        /// </summary>
        /// <param name="path">文件地址</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] File2Bytes(string path)
        {
            if (!File.Exists(path))
            {
                return new byte[0];
            }

            FileInfo fi = new FileInfo(path);
            byte[] buff = new byte[fi.Length];


            FileStream fs = fi.OpenRead();
            fs.Read(buff, 0, Convert.ToInt32(fs.Length));
            fs.Close();


            return buff;
        }

        /// <summary>
        /// 删除文件夹下的所有文件
        /// </summary>
        /// <param name="dirRoot"></param>
        public static void DeleteDirAllFile(string dirRoot)
        {
            DirectoryInfo aDirectoryInfo = new DirectoryInfo(Path.GetDirectoryName(dirRoot));
            FileInfo[] files = aDirectoryInfo.GetFiles("*.*", SearchOption.AllDirectories);
            foreach (FileInfo f in files)
            {
                File.Delete(f.FullName);
            }
        }
    }
}
